//*****************************************
// Oscar Rodriguez Polo    c) 2013
// humsat_time.cpp
// class to manage Universal Time in HUMSAT
//*****************************************

//*****************************************************************************
//              LAUNCH UNIVERSAL TIME

//October the ??th
#define SRG_HUMSAT_LAUNCH_DATETIME_YEAR   15
#define SRG_HUMSAT_LAUNCH_DATETIME_DAY    0
#define SRG_HUMSAT_LAUNCH_DATETIME_HOUR   0
#define SRG_HUMSAT_LAUNCH_DATETIME_MINUTE 0
#define SRG_HUMSAT_LAUNCH_DATETIME_SECOND 0

#include <public/humsat_unitime.h>
#include <public/edroombp.h>
#include <iostream>
using namespace std;


//***********************************************************************
//*************** STATIC VARS ***********************************************
//***********************************************************************

uint32_t CUniTime::UniTimeRef=0;
Pr_Time CUniTime::LocalTimeRef;



//***********************************************************************
//*************** METHODS ***********************************************
//***********************************************************************

/**
* Init
*/
void CUniTime::Init(){

      LocalTimeRef.GetTime();
      CUniTime aux;
      aux.BuildUniTime(  SRG_HUMSAT_LAUNCH_DATETIME_YEAR,
										SRG_HUMSAT_LAUNCH_DATETIME_DAY,
										SRG_HUMSAT_LAUNCH_DATETIME_HOUR,
										SRG_HUMSAT_LAUNCH_DATETIME_MINUTE,
										SRG_HUMSAT_LAUNCH_DATETIME_SECOND);

      UniTimeRef=aux.GetUniTimeSeconds();
}

/**
* UpdateCurrentUniTime
*/

void CUniTime::UpdateCurrentUniTime(uint32_t currentUniTime){
      LocalTimeRef.GetTime();
      UniTimeRef=currentUniTime;

}

/**
 GetCurrentUniversalTimeSecns
 */

uint32_t CUniTime::GetCurrentUniTimeSeconds() {
     Pr_Time currentTime;
     currentTime.GetTime();
     currentTime-=LocalTimeRef;
     return (UniTimeRef + currentTime.Secns());


}




//******************************************************************************
//					ExtractFromUniTime

void CUniTime::ExtractFromUniTime(TEDROOMByte & year, TEDROOMWord16 & day
									, TEDROOMByte & hour, TEDROOMByte &minute
									, TEDROOMByte & seconds){

        uint32_t aux;
        aux=m_unitime;
        seconds=aux%60;
        aux=(aux-seconds)/60; //In minutes
        minute=aux%60;
        aux=(aux-minute)/60; //In hours
        hour=aux%24;
        aux=(aux-hour)/24; //In days

        //Define Years number
        year=aux/365;
        if (year>0){
            day=aux-year*365; //Extra days
				//If extra days are > 29 Feb Counts= year/4 +1
            if (day >= ((year-1)/4 +1))
                day=day-((year-1)/4 +1);
            else{                          //No extra days, decrease year
                year--;
                day=day+365-((year-1)/4 +1);
            }
        }else day=aux;

}


//******************************************************************************
//			      	BuildUniTime

void CUniTime::BuildUniTime(uint8_t year,
 						    uint16_t day,
        					uint8_t hour,
        					uint8_t minute,
        					uint8_t second){

		uint32_t seconds;
        uint32_t totalDays;

        if(year>0)					//aux has the days of the complete years
                totalDays=year*365 + (year-1)/4 +1 + day;
        else
            totalDays= day ;

        seconds=((totalDays*24 + hour)*60 + minute)*60 + second;

        m_unitime=seconds;


}


//******************************************************************************
//					CurrentUniTime

void CUniTime::SetWithCurrentUniTime(){

        m_unitime=GetCurrentUniTimeSeconds();

}


//******************************************************************************
//				TraceUniTime

void CUniTime::TraceUniTime(){

		uint8_t Year, Hour, Minute, Seconds;

        uint16_t Day;
        CUniTime time;

        time.SetWithCurrentUniTime();
        time.ExtractFromUniTime( Year, Day, Hour, Minute, Seconds);

        cout << (int) Year <<"/" << (int)Day << "/ " << (int)Hour  << " : " << (int)Minute << " : " << (int)Seconds << "\t";

}


